package terminal.ui.contexts;

import kret.ui.AbstractFrameContext;
import terminal.interfaces.ISerialPort;
import terminal.model.SerialModel;
import kret.ui.ActionManager;
import terminal.model.TerminalModel;
import terminal.model.TerminalStringListener;
import terminal.ui.forms.FrameMain;
import terminal.model.KeyEventToSerialPortProxy;

/**
 *
 * @author P. Podwapinski
 */
public class FrameMainContext extends AbstractFrameContext 
{
    public FrameMainContext( ActionManager actionManager, FrameMain frame, SerialModel serialModel )
    {
        super( actionManager, frame );
        
        m_frameMain = frame;
        
        if ( null != serialModel )
        {
            m_serialPort = serialModel.getSerialPort();
            
            KeyEventToSerialPortProxy keyProxy = new KeyEventToSerialPortProxy( m_serialPort );
            m_frameMain.addKeyListener( keyProxy );
            
            TerminalModel terminalModel = new TerminalModel();
            TerminalStringListener terminalStringListener = new TerminalStringListener( terminalModel );
            
            m_frameMain.setTextAreaDocument( terminalModel.getDocument() );
            
            serialModel.getDataProcessor().addListener( terminalStringListener );
        }
        
        bindActions();
        applyInitialActionStates();
    }
    
    @Override public void onFrameClosed()
    {
        System.exit(0);
    }
    
    @Override public void onFrameOpened()
    {
        updateStatus();
    }
    
    @Override public void onFrameActivated()
    {
        updateStatus();
    }    
    
    @Override public void onCommandExecuted( final String command )
    {
        if ( null != command )
        {
            switch ( command )
            {                   
                case COMMAND_APP_EXIT:
                {
                    closeFrame();
                }
                break;
                
                case COMMAND_DIALOG_OPENPORT_SHOW:
                {
                    showChildContext( "DLG_PORTOPEN" );
                }
                break;
                                       
                case COMMAND_PORT_CLOSE:
                {
                    closePort();
                    updateStatus();
                }
                break;
                    
                case COMMAND_DIALOG_ABOUT_SHOW:
                {
                    showChildContext( "DLG_ABOUT" );
                }
                break;
            }            
        } 
    }
    
    
    private void closePort()
    {
        if ( null != m_serialPort )
        {
            if ( m_serialPort.isOpened() )
            {
                m_serialPort.close();
                getCommandAdapter().setActionEnabledByCommand( COMMAND_PORT_CLOSE, false );
                getCommandAdapter().setActionEnabledByCommand( COMMAND_DIALOG_OPENPORT_SHOW, true );
            }
        }
    }
    
    private void bindActions()
    {   
        getCommandAdapter().bindToCommand( m_frameMain.getTriggerExit(), COMMAND_APP_EXIT );
        getCommandAdapter().bindToCommand( m_frameMain.getTriggerPortOpen(), COMMAND_DIALOG_OPENPORT_SHOW );
        getCommandAdapter().bindToCommand( m_frameMain.getTriggerPortClose(), COMMAND_PORT_CLOSE );
        getCommandAdapter().bindToCommand( m_frameMain.getTriggerAbout(), COMMAND_DIALOG_ABOUT_SHOW );
    }
    
    private void applyInitialActionStates()
    {
        getCommandAdapter().setActionEnabledByCommand( COMMAND_PORT_CLOSE, false );
    }
    
    private void updateStatus()
    {
        String statusString = "Port Closed";
        
        if ( null != m_serialPort )
        {
            if ( m_serialPort.isOpened() )
            {
                statusString = buildStatus( m_serialPort.getPortName(), m_serialPort.getBaudrate() );
            }
        }        
        
        m_frameMain.setStatusText( statusString );
    }
    
    private static String buildStatus( final String portName, final String baudRate )
    {
        return portName + " @ " + baudRate + " bps";
    }
    
    FrameMain m_frameMain;
    ISerialPort m_serialPort;
}
